#include <common.h>
#include <device/map.h>
#include <SDL2/SDL.h>
enum {
  reg_freq,
  reg_channels,
  reg_samples,
  reg_sbuf_size,
  reg_init,
  reg_count,
  nr_reg
};

static uint8_t *sbuf = NULL;
static uint32_t *audio_base = NULL;

int freq;
int channels;
int samples;
int init;
static volatile int count = 0;


static void audio_play(void *userdata, uint8_t *stream, int len) {
  if(!audio_base[reg_init]){
    count = audio_base[reg_count];
    int nread = len;
    if (count < len) nread = count;
      memcpy(stream,sbuf,nread);
//      printf("r,count:%d,nread:%d\n",audio_base[reg_count],nread);
//      sbuf += nread;
      memset(sbuf,0,nread);
      memcpy(sbuf,sbuf+nread,count-nread); 
//    printf("freq:%dchannels:%dsamples:%d\n",audio_base[reg_freq],audio_base[reg_channels],audio_base[reg_samples]);      
      count -= nread;
    if (len > nread) {
      memset(stream + nread, 0, len - nread);
    }
    audio_base[reg_count] = count;
  }
}

static void audio_io_handler(uint32_t offset, int len, bool is_write) {
void init_sdl();
//  assert(is_write);
  switch (offset) {
    case 0: case 4: case 8: 
      	    init_sdl();
      break;
    case 10:
	break;
    case 0x14:
/*	if(!is_write){
	audio_base[reg_count] = count;
	}
	else
	count = audio_base[reg_count];*/
	break;

    }
}

void init_sdl(){
	freq = audio_base[reg_freq];
	channels = audio_base[reg_channels];
	samples = audio_base[reg_samples];
	init = audio_base[reg_init];
	SDL_AudioSpec s = {};
	s.format = AUDIO_S16SYS;
	s.userdata = NULL;
	s.freq = freq;
	s.channels = channels;
	s.samples = samples;
	s.callback = audio_play;

	int ret = SDL_InitSubSystem(SDL_INIT_AUDIO);
	if (ret == 0){
		SDL_OpenAudio(&s,NULL);
		SDL_PauseAudio(0);
	}
}

void init_audio() {
  uint32_t space_size = sizeof(uint32_t) * nr_reg;
  audio_base = (uint32_t *)new_space(space_size);
#ifdef CONFIG_HAS_PORT_IO
  add_pio_map ("audio", CONFIG_AUDIO_CTL_PORT, audio_base, space_size, audio_io_handler);
#else
  add_mmio_map("audio", CONFIG_AUDIO_CTL_MMIO, audio_base, space_size, audio_io_handler);
#endif
 // printf("%d\n",CONFIG_SB_SIZE);
  sbuf = (uint8_t *)new_space(CONFIG_SB_SIZE);
  add_mmio_map("audio-sbuf", CONFIG_SB_ADDR, sbuf, CONFIG_SB_SIZE, NULL);
	
  }
